package com.caseprocessing.service;

import com.caseprocessing.model.*;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 文档分割器
 * 负责将整个案卷按照文书边界进行智能分割
 */
public class DocumentSplitter {
    
    private DirectoryBasedSplitter directoryBasedSplitter;
    private ContentBasedSplitter contentBasedSplitter;
    
    public DocumentSplitter() {
        this.directoryBasedSplitter = new DirectoryBasedSplitter();
        this.contentBasedSplitter = new ContentBasedSplitter();
    }
    
    /**
     * 主分割方法
     * 优先使用目录分割，如果目录不可用则使用内容分割
     */
    public List<DocumentSegment> splitDocument(CaseDocument caseDoc) {
        List<DocumentSegment> segments = new ArrayList<>();
        
        try {
            // 尝试基于目录的精确分割
            segments = directoryBasedSplitter.splitByDirectory(caseDoc);
            
            if (segments.isEmpty()) {
                // 目录分割失败，使用内容分析分割
                segments = contentBasedSplitter.splitByContent(caseDoc);
            }
            
            // 为分割结果填充页面内容
            fillSegmentPages(caseDoc, segments);
            
            // 验证分割结果
            validateSegments(segments, caseDoc.getTotalPages());
            
        } catch (Exception e) {
            // 分割失败时返回单个片段
            segments = createFallbackSegment(caseDoc);
        }
        
        return segments;
    }
    
    /**
     * 为分割片段填充页面内容
     */
    private void fillSegmentPages(CaseDocument caseDoc, List<DocumentSegment> segments) {
        for (DocumentSegment segment : segments) {
            List<Page> segmentPages = caseDoc.getPageRange(segment.getStartPage(), segment.getEndPage());
            segment.setPages(segmentPages);
        }
    }
    
    /**
     * 验证分割结果的完整性
     */
    private void validateSegments(List<DocumentSegment> segments, int totalPages) {
        if (segments.isEmpty()) {
            throw new IllegalStateException("分割结果为空");
        }
        
        // 检查页面覆盖的完整性
        Set<Integer> coveredPages = new HashSet<>();
        for (DocumentSegment segment : segments) {
            for (int page = segment.getStartPage(); page <= segment.getEndPage(); page++) {
                if (coveredPages.contains(page)) {
                    System.out.println("警告：页面 " + page + " 被多个片段覆盖");
                }
                coveredPages.add(page);
            }
        }
        
        // 检查是否有遗漏的页面
        for (int page = 1; page <= totalPages; page++) {
            if (!coveredPages.contains(page)) {
                System.out.println("警告：页面 " + page + " 未被任何片段覆盖");
            }
        }
    }
    
    /**
     * 创建后备分割方案（整个文档作为一个片段）
     */
    private List<DocumentSegment> createFallbackSegment(CaseDocument caseDoc) {
        DocumentSegment segment = new DocumentSegment("fallback_001", 1, caseDoc.getTotalPages());
        segment.setTitle("未分类文档");
        segment.setDocumentType(DocumentType.OTHER);
        segment.setConfidence(0.1);
        
        return Arrays.asList(segment);
    }
    
    /**
     * 基于目录的文档分割器
     */
    static class DirectoryBasedSplitter {
        
        public List<DocumentSegment> splitByDirectory(CaseDocument caseDoc) {
            List<DocumentSegment> segments = new ArrayList<>();
            
            // 查找并解析目录
            Directory directory = parseDirectory(caseDoc);
            if (directory == null || directory.getEntries().isEmpty()) {
                return segments; // 返回空列表，表示目录分割失败
            }
            
            // 根据目录条目创建分割片段
            for (DirectoryEntry entry : directory.getEntries()) {
                DocumentSegment segment = createSegmentFromDirectoryEntry(entry);
                if (segment.isValid()) {
                    segments.add(segment);
                }
            }
            
            return segments;
        }
        
        /**
         * 解析案卷目录
         */
        private Directory parseDirectory(CaseDocument caseDoc) {
            // 查找目录页
            List<Page> directoryPages = findDirectoryPages(caseDoc);
            if (directoryPages.isEmpty()) {
                return null;
            }
            
            Directory directory = new Directory();
            List<DirectoryEntry> entries = new ArrayList<>();
            
            // 解析每个目录页
            for (Page page : directoryPages) {
                entries.addAll(parseDirectoryPage(page));
            }
            
            directory.setEntries(entries);
            return directory;
        }
        
        /**
         * 查找目录页
         */
        private List<Page> findDirectoryPages(CaseDocument caseDoc) {
            return caseDoc.getPages().stream()
                    .filter(page -> isDirectoryPage(page))
                    .collect(Collectors.toList());
        }
        
        /**
         * 判断是否为目录页
         */
        private boolean isDirectoryPage(Page page) {
            String content = page.getFullText();
            return content.contains("卷内文件目录") || 
                   (content.contains("序号") && content.contains("文号") && 
                    content.contains("责任者") && content.contains("题名"));
        }
        
        /**
         * 解析单个目录页
         */
        private List<DirectoryEntry> parseDirectoryPage(Page page) {
            List<DirectoryEntry> entries = new ArrayList<>();
            String content = page.getFullText();
            
            // 按行分割内容
            String[] lines = content.split("\n");
            
            for (String line : lines) {
                DirectoryEntry entry = parseDirectoryLine(line.trim());
                if (entry != null) {
                    entries.add(entry);
                }
            }
            
            return entries;
        }
        
        /**
         * 解析目录行
         * 假设格式：序号 | 文号 | 责任者 | 题名 | 日期 | 页号
         */
        private DirectoryEntry parseDirectoryLine(String line) {
            if (line.isEmpty() || !line.matches("^\\d+.*")) {
                return null; // 跳过非条目行
            }
            
            try {
                // 简化的解析逻辑（实际应该更复杂）
                String[] parts = line.split("\\s+", 6);
                if (parts.length < 4) {
                    return null;
                }
                
                DirectoryEntry entry = new DirectoryEntry();
                entry.setSequenceNumber(Integer.parseInt(parts[0]));
                entry.setDocumentNumber(parts.length > 1 ? parts[1] : "");
                entry.setResponsibleParty(parts.length > 2 ? parts[2] : "");
                entry.setTitle(parts.length > 3 ? parts[3] : "");
                entry.setDate(parts.length > 4 ? parts[4] : "");
                
                // 解析页号范围
                if (parts.length > 5) {
                    parsePageRange(entry, parts[5]);
                }
                
                return entry;
                
            } catch (Exception e) {
                return null; // 解析失败
            }
        }
        
        /**
         * 解析页号范围
         */
        private void parsePageRange(DirectoryEntry entry, String pageInfo) {
            try {
                if (pageInfo.contains("-")) {
                    String[] range = pageInfo.split("-");
                    entry.setStartPage(Integer.parseInt(range[0].trim()));
                    entry.setEndPage(Integer.parseInt(range[1].trim()));
                } else {
                    int page = Integer.parseInt(pageInfo.trim());
                    entry.setStartPage(page);
                    entry.setEndPage(page);
                }
            } catch (NumberFormatException e) {
                // 页号解析失败，使用默认值
                entry.setStartPage(1);
                entry.setEndPage(1);
            }
        }
        
        /**
         * 从目录条目创建文档片段
         */
        private DocumentSegment createSegmentFromDirectoryEntry(DirectoryEntry entry) {
            String segmentId = "dir_" + String.format("%03d", entry.getSequenceNumber());
            
            DocumentSegment segment = new DocumentSegment(segmentId, 
                                                         entry.getStartPage(), 
                                                         entry.getEndPage());
            segment.setTitle(entry.getTitle());
            segment.setDocumentNumber(entry.getDocumentNumber());
            segment.setResponsibleParty(entry.getResponsibleParty());
            segment.setDate(entry.getDate());
            segment.setConfidence(0.9); // 基于目录的分割置信度较高
            
            return segment;
        }
    }
    
    /**
     * 基于内容的文档分割器
     */
    static class ContentBasedSplitter {
        
        public List<DocumentSegment> splitByContent(CaseDocument caseDoc) {
            List<DocumentSegment> segments = new ArrayList<>();
            List<Page> pages = caseDoc.getPages();
            
            int segmentStart = 1;
            int segmentCounter = 1;
            
            for (int i = 0; i < pages.size(); i++) {
                Page currentPage = pages.get(i);
                
                // 检查是否为文档开始页
                if (isDocumentStart(currentPage) && i > 0) {
                    // 创建前一个文档片段
                    DocumentSegment segment = createContentBasedSegment(
                        segmentCounter++, segmentStart, i, caseDoc);
                    segments.add(segment);
                    
                    segmentStart = i + 1;
                }
            }
            
            // 创建最后一个片段
            if (segmentStart <= pages.size()) {
                DocumentSegment segment = createContentBasedSegment(
                    segmentCounter, segmentStart, pages.size(), caseDoc);
                segments.add(segment);
            }
            
            return segments;
        }
        
        /**
         * 判断是否为文档开始页
         */
        private boolean isDocumentStart(Page page) {
            // 1. 检测标题模式
            boolean hasTitle = detectTitlePattern(page);
            
            // 2. 检测文号格式
            boolean hasDocNumber = detectDocumentNumber(page);
            
            // 3. 检测发文机关
            boolean hasAgency = detectIssuingAgency(page);
            
            return hasTitle && (hasDocNumber || hasAgency);
        }
        
        /**
         * 检测标题模式
         */
        private boolean detectTitlePattern(Page page) {
            if (page.getTextBlocks() == null) return false;
            
            // 查找标题类型的文本块
            for (TextBlock block : page.getTextBlocks()) {
                if (block.isTitle() && isLegalDocumentTitle(block.getText())) {
                    return true;
                }
            }
            
            return false;
        }
        
        /**
         * 判断是否为法律文书标题
         */
        private boolean isLegalDocumentTitle(String text) {
            String[] titleKeywords = {
                "决定书", "告知书", "笔录", "清单", "申辩书", "意见书", "记录", "通知书"
            };
            
            String lowerText = text.toLowerCase();
            for (String keyword : titleKeywords) {
                if (lowerText.contains(keyword)) {
                    return true;
                }
            }
            
            return false;
        }
        
        /**
         * 检测文号格式
         */
        private boolean detectDocumentNumber(Page page) {
            if (page.getTextBlocks() == null) return false;
            
            return page.getTextBlocks().stream()
                    .anyMatch(TextBlock::isDocumentNumber);
        }
        
        /**
         * 检测发文机关
         */
        private boolean detectIssuingAgency(Page page) {
            String content = page.getFullText();
            String[] agencyKeywords = {
                "人民政府", "执法局", "监察局", "公安局", "工商局", "税务局", "建设局"
            };
            
            for (String keyword : agencyKeywords) {
                if (content.contains(keyword)) {
                    return true;
                }
            }
            
            return false;
        }
        
        /**
         * 创建基于内容的文档片段
         */
        private DocumentSegment createContentBasedSegment(int segmentNumber, 
                                                         int startPage, 
                                                         int endPage, 
                                                         CaseDocument caseDoc) {
            String segmentId = "content_" + String.format("%03d", segmentNumber);
            
            DocumentSegment segment = new DocumentSegment(segmentId, startPage, endPage);
            
            // 尝试从第一页提取标题和文号
            if (startPage <= caseDoc.getPages().size()) {
                Page firstPage = caseDoc.getPages().get(startPage - 1);
                extractSegmentMetadata(segment, firstPage);
            }
            
            segment.setConfidence(0.6); // 基于内容的分割置信度较低
            
            return segment;
        }
        
        /**
         * 从页面中提取片段元数据
         */
        private void extractSegmentMetadata(DocumentSegment segment, Page page) {
            if (page.getTextBlocks() == null) return;
            
            // 提取标题
            for (TextBlock block : page.getTextBlocks()) {
                if (block.isTitle() && segment.getTitle() == null) {
                    segment.setTitle(block.getText().trim());
                }
                
                if (block.isDocumentNumber() && segment.getDocumentNumber() == null) {
                    segment.setDocumentNumber(block.getText().trim());
                }
                
                if (block.containsDate() && segment.getDate() == null) {
                    segment.setDate(extractDateFromText(block.getText()));
                }
            }
            
            // 如果没有找到标题，使用默认标题
            if (segment.getTitle() == null || segment.getTitle().isEmpty()) {
                segment.setTitle("文档片段 " + segment.getSegmentId());
            }
        }
        
        /**
         * 从文本中提取日期
         */
        private String extractDateFromText(String text) {
            java.util.regex.Pattern pattern = java.util.regex.Pattern.compile("(\\d{8})");
            java.util.regex.Matcher matcher = pattern.matcher(text);
            
            if (matcher.find()) {
                return matcher.group(1);
            }
            
            return null;
        }
    }
}